/**
 * ECP Web开发通用选择控件.
 * Copyright(c) 2012-2020 YGSoft.Inc
 * @author zhengxianwei 
 * @date 2016-07-04
 */
define(["jquery","ecp.service","ecp.utils","ecp.component.comboBox","ecp.utils.i18n"],function($,ecp,utils,comboBox,i18n){
	/**
	 * 默认参数.
	 */
	var defaultOption = {
		multiple:false,
		isShowMore:true,
		allowClear:true,
		title:i18n.select.entitiTitle,
		placeholder:i18n.select.selecting
	};
	
	/**
	 * 声明EntitySelect对象.
	 * @param {Object} control 控件的jQuery对象，即占位符。
	 * @param {option} option 控件的属性对象
	 */
	var EntitySelect = function(control,option){
		if(!control || control.length === 0){return;}
		//初始化
		this.init(control,option);
		//渲染控件
		this._render();
	}
	/**
	 * 通过原型定义相关方法，比如渲染、赋值等等.
	 */
	EntitySelect.prototype = {
			/**
			 * 初始化.
			 * @param {Object} control 控件的jQuery对象，即占位符。
	    	 * @param {Object} option 控件的属性对象
			 */
			init: function(control, option){
				this.control = control;
				//获取html中占位符的属性
				var dOpt = control.attr("data-option");
				if(dOpt && dOpt.length !== 0){
					dOpt = $.parseJSON(dOpt);
				}else{
					dOpt = {};
				}
				//合并属性，优先级：option > data-option > defaultOption
				var opt = this.option = $.extend(true,{},defaultOption,dOpt,option);
				//更多点击事件
				this.option.clickMore = $.proxy(this._clickMore, this);
				//关闭回调事件
				this.option.closeCallBack = $.proxy(this._closeCallBack, this);
				if(!this.option.data){
					this.option.dataSource = this._dataSource;
				}
				var treeOpt = opt.entityTree;
				if(treeOpt){
					if(!opt.idField && treeOpt.treeValueField){
						this.option.idField = treeOpt.treeValueField;
					}
					if(!opt.textField && treeOpt.treeTextField){
						this.option.textField = treeOpt.treeTextField;
					}
				}
			},
			
			/**
	    	 * 渲染控件.
	    	 */
			_render: function(){
				this.comboBox = this.control.comboBox(this.option);
				this.comboBox.base(this);
	    	},
	    	
	    	/**
	    	 * 获得comboBox对象.
	    	 */
	    	getComboBox: function(){
	    		return this.comboBox;
	    	},
	    	
	    	/**
	    	 * 继承comboBox表格中渲染须实现的方法.
	    	 */
	    	inheritGridMethod: function(obj){
				this.comboBox.inheritGridMethod(obj);
	    	},
	    	
			/**
	    	 * 查询下拉数据.
	    	 * @param {Function} callback 回调
	    	 * @param {Object} option 控件的属性对象
	    	 * @param {Object} filter 过滤对象
	    	 */
			_dataSource: function(callback,option,filter){
	    		var listDatas = option.listDatas;
	    		if($.isFunction(listDatas)){
	    			listDatas.call(this, callback, option, filter);
	    		}
			},
			
	    	/**
			 * 设置树节点数据回调.
			 */
			setTreeDatas: function(handler){
				if($.isFunction(handler)){
					this.option.treeDatas = handler;
				}
			},
			
			/**
			 * 设置表格数据回调.
			 */
			setGridDatas: function(handler){
				if($.isFunction(handler)){
					this.option.gridDatas = handler;
				}
			},
			
	    	/**
	    	 * 点击事件. 
	    	 */
	    	_clickMore: function(){
	    		var me = this;
	    		var vals = me.comboBox.value();
	    		//渲染树
	    		if(!this.popentity || this.option.noCache !== false){
	    			require(["ecp.component.popentity"],function(popentity){
	    				me.popentity = new popentity(me.option);
		    			me.popentity.treeEvents = me.treeEvents;
						me.popentity.setSelectValue(vals);
	    			})
	    		}else{
	    			this.popentity.show();
	    			this.popentity.treeEvents = this.treeEvents;
					this.popentity.setSelectValue(vals);
	    		}
	    		//窗口打开
				me.control.attr("openWin",true);
	    	},
	    	
	    	/**
	    	 * 绑定树事件.
	    	 */
	    	bindTreeEvent: function(event,handler){
	    		if(utils.notEmpty(event) && utils.notEmpty(handler)){
	    			if(!this.treeEvents){this.treeEvents = [];}
	    			this.treeEvents.push({event:event,handler:handler});
	    		}
	    	},
	    	
	    	/**
	    	 * 解除树事件.
	    	 */
	    	unBindTreeEvent: function(event){
	    		if(utils.notEmpty(event)){
	    			var te = this.treeEvents;
	    			if(te && te.length !== 0){
	    				for(var i=te.length-1; i>=0; i--){
	    					if(te[i].event === event){
	    						te.removeAt(i);
	    					}
	    				}
	    			}
	    		}
	    	},
	    	
	    	/**
	    	 * 关闭回调.给下拉框设置值.
	    	 */
	    	_closeCallBack: function(data){
	    		//重新设置一下ID，因为在构造树的时候把会创建ID，这时的ID不一定正确,因为取的是treeCodeField字段
	    		if($.type(data) == "object" && !$.isEmptyObject(data)){ 
	    			data = [data];
	    		}
	    		var opt = this.comboBox.option;
	    		if(data){
		    		$.each(data,function(){
		    			this.id = this[opt.idField];
		    		})
	    		}
	    		this.comboBox.value(data);
	    		//窗口关闭
	    		this.control.attr("openWin","");
	    		//关闭后回调函数
	    		var afterClose = this.option.afterClose;
	    		if($.isFunction(afterClose)){
	    			afterClose.call(this, data, this.option);
	    		}
	    	}
	};
	
	(function($) {
		var old = $.fn.entityselect;
		/**
		 * 集成到jquery中，暴露entityselect接口，渲染下拉控件
		 * @param {Object | String | Boolean} option
		 *  为object时表示渲染控件需要的参数;
		 *  为string时表示调用控件的方法；
		 *  为boolean时表示获取控件对象
		 */
		$.fn.entityselect = function(option){
			var me = this;
			if(!me || me.length === 0){
				if(window.console){
					window.console.error("ecp.component.entityselect"+i18n.select.renderError);
				}
				return;
			}
			option = option || {};
			var type = typeof(option);
			//如果第一个参数传入的是对象或空则初始化空件，如果传入的是字符串，则认为是调用里面的内部方法。
			if (type === "object") {
				var ess = [];
				this.each(function() {
					var instanceOption = $.extend({}, option, true);
					var instance = new EntitySelect($(this), instanceOption);
					this.entityselect = instance;
					ess.push(instance);
				});
				if(ess.length === 1){
					ess = ess[0];
				}
				return ess;
			} else if (type === "string") {
				var args = Array.prototype.slice.call(arguments, 1);
				if (EntitySelect.prototype[option]) {
					return EntitySelect.prototype[option].call(args);
				}
			} else if (option === true) {
				return me[0] && me[0].entityselect;
			}
		};
		$.fn.entityselect.Constructor = EntitySelect;
		$.fn.entityselect.noConflict = function() {
			$.fn.entityselect = old;
			return this;
		};
	}(jQuery));
	return EntitySelect;
});